Use case: PWM output in interrupt mode

HAL1

HAL2

Channel configuration

  • To initialize the TIM PWM channels according to the specified parameters, call:

    • HAL_TIM_PWM_ConfigChannel.

Start PWM signal in interrupt mode

  • The function HAL_TIM_PWM_Start_IT(&htim, TIM_CHANNEL_x) is used to enable:

    • The TIMx peripheral.

    • The selected channel x.

    • The capture compare x interrupt.

TIMx IRQ handler

  • Inside the interrupt handler for TIMx, the user calls the global IRQ handler of the TIM driver HAL_TIM_IRQHandler() to handle the capture compare x interrupt request.

Callback function

  • The function HAL_TIM_PWM_PulseFinishedCallback() is called when the PWM pulse is finished.

Channel configuration

  • Replace the channel configuration by the following sequence:

    • HAL_TIM_OC_SetConfigChannel

    • HAL_TIM_OC_SetConfigCompareUnit

Start PWM signal in interrupt mode

  • The function HAL_TIM_OC_StartChannel_IT(&htim, TIM_CHANNEL_x) is used to enable:

    1. The selected channel x.

    2. The capture compare x interrupt.

  • The function HAL_TIM_Start() is used to enable and start the TIMx.

TIMx IRQ handler

  • Inside the interrupt handler for TIMx, the user can call either:

    • The global IRQ handler HAL_TIM_IRQHandler() to handle the capture compare x interrupt request, or

    • The single process IRQ handler for specific interrupt events in this case HAL_TIM_CC_IRQHandler().

Callback function

  • The function HAL_TIM_CompareMatchCallback() is called when the output compare event occurs.

Important

When using PWM with DMA, it is mandatory to call the function HAL_TIM_OC_EnableChannelComparePreload.

Sequence diagram

PWM output

@startuml
skinparam maxMessageSize 440
' To add a number by line
'autonumber

title "PWM Output in HAL 1"

' Fix order of each column
participant "User Application" as App
participant "HAL TIM" as Driver

participant "IT" as IT

group Initialization and configuration of TIMx
App -[hidden]>Driver
end


group Configuration of channel


App -> Driver : \n<b><font color=purple>HAL_TIM_PWM_ConfigChannel</b>(channel = <font color=blue>HAL_TIM_CHANNEL_<b>x</b>,\n(TIM_OC_InitTypeDef) {\n.OCPolarity = TIM_OCPOLARITY_HIGH,\n.OCIdleState = TIM_OCIDLESTATE_RESET,\n.OCMode = TIM_OCMODE_PWM1,\n.Pulse = PULSE1_VALUE})
Driver --> App : HAL_O

end

group Start TIMx in IT mode

App -> Driver : <b><font color=blue>HAL_TIM_PWM_Start_IT</b>(&htim, HAL_TIM_CHANNEL_<b>x</b>)
Driver --> App : HAL_OK
Driver->Driver : Enable capture compare interrupt\nEnable TIMx counter
Driver --> App : HAL_OK
IT <[#red]-] : <font color=red><b>TIMx IRQ
IT -> Driver : HAL_TIM_IRQHandler()
Driver -> Driver : Clear flag
Driver -> App: <b><font color=green>HAL_TIM_PWM_PulseFinishedCallback</b>()
App --> Driver
Driver --> IT

end
@enduml

Code snippet

HAL1

HAL2

/* Declaration of tim handle */
TIM_HandleTypeDef htim3;

/* Ensure that all required peripherals
(TIM(timer, channel), GPIO, NVIC, etc.) are configured properly
before starting PWM output.*/
.............

/* Start the PWM output in interrupt mode */
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2);

/* User must call the Interrupt Handler
  functions in TIM3 global interrupt */

void TIM3_IRQHandler(void)
{
    /* Code to execute at each interrupt */
    HAL_TIM_IRQHandler(&htim3);
}

/* Call the callback function */

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
        /* Code to execute at each compare match interrupt
          For example, toggle an LED */
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
 /* Declaration of the tim handle */
 hal_tim_handle_t htim3;

 /* Ensure that all required peripherals
 (TIM(timer, channel), GPIO, NVIC, etc.) are configured properly
 before starting PWM output.*/
      .............

/* Start a timer's output channel in interrupt mode. */
 HAL_TIM_OC_StartChannel_IT(&htim3, HAL_TIM_CHANNEL_2);

 /* Start the timer */
 HAL_TIM_Start(&htim3);

 /* User must call the Interrupt Handler
  functions in TIM2 global interrupt */

 void TIM2_IRQHandler(void)
 {
     /* Code to execute at each interrupt */
     HAL_TIM_IRQHandler(&htim3);
 }

 /* Call the callback function */

 void HAL_TIM_CompareMatchCallback(hal_tim_handle_t *htim,
                          hal_tim_channel_t channel);
 {
     /* Code to execute at each interrupt
        For example, toggle an LED */
     HAL_GPIO_TogglePin(HAL_GPIOA, HAL_GPIO_PIN_5);
 }

Key changes

  1. PWM configuration APIs are replaced by the output compare configuration sequence in HAL2.

  2. Channel start in interrupt mode uses HAL_TIM_OC_StartChannel_IT() and timer start uses HAL_TIM_Start().

  3. The PWM pulse finished callback is replaced by the output compare match callback HAL_TIM_CompareMatchCallback().